package cn.edu.tju.elm.service.impl;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.edu.tju.core.security.SecurityUtils;
import cn.edu.tju.elm.dto.BusinessDto;
import cn.edu.tju.elm.dto.RefundDto;
import cn.edu.tju.elm.model.Order;
import cn.edu.tju.elm.model.Refund;
import cn.edu.tju.elm.repository.OrderRepository;
import cn.edu.tju.elm.repository.RefundRepository;
import cn.edu.tju.elm.service.RefundService;

/**
 * 退款服务实现类
 */
@Service
public class RefundServiceImpl implements RefundService {

    @Autowired
    private OrderRepository orderRepository;
    
    @Autowired
    private RefundRepository refundRepository;
    
    @Override
    @Transactional
    public Order applyRefund(Long orderId, String reason, String detail) {
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("订单不存在"));
        
        // 获取当前用户ID
        String username = SecurityUtils.getCurrentUsername()
                .orElseThrow(() -> new RuntimeException("用户未登录"));
        
        // 验证订单是否属于当前用户
        if (!order.getCustomer().getUsername().equals(username)) {
            throw new RuntimeException("无权操作此订单");
        }
        
        // 检查订单状态，只有状态为2(待接单)、3(制作中)、4(已送达)的订单才能申请退款
        if (order.getOrderState() < 2 || order.getOrderState() > 4) {
            throw new RuntimeException("当前订单状态不允许申请退款");
        }
        
        // 检查是否已有待处理的退款申请
        if (refundRepository.findByOrderId(orderId).stream()
                .anyMatch(r -> r.getStatus() == 0)) {
            throw new RuntimeException("此订单已有待处理的退款申请");
        }
        
        // 创建退款申请
        Refund refund = new Refund();
        refund.setOrder(order);
        refund.setReason(reason);
        refund.setDetail(detail);
        refund.setStatus(0); // 0: 待审核
        refund.setApplyTime(new Date());
        refundRepository.save(refund);
        
        // 更新订单状态为5(退款审核中)
        order.setOrderState(5);
        return orderRepository.save(order);
    }
    
    @Override
    @Transactional
    public Order processRefund(Long refundId, boolean approved, String rejectReason) {
        Refund refund = refundRepository.findById(refundId)
                .orElseThrow(() -> new RuntimeException("退款申请不存在"));
        
        // 检查退款状态是否为待审核
        if (refund.getStatus() != 0) {
            throw new RuntimeException("该退款申请已处理");
        }
        
        // 获取关联订单
        Order order = refund.getOrder();
        
        // 获取当前用户ID
        String username = SecurityUtils.getCurrentUsername()
                .orElseThrow(() -> new RuntimeException("用户未登录"));
        
        // 验证商家身份
        if (!order.getBusiness().getBusinessOwner().getUsername().equals(username)) {
            throw new RuntimeException("无权处理此退款申请");
        }
        
        // 更新退款状态
        refund.setStatus(approved ? 1 : 2); // 1: 已批准, 2: 已拒绝
        if (!approved && rejectReason != null) {
            refund.setRejectReason(rejectReason);
        }
        refund.setProcessTime(new Date());
        refundRepository.save(refund);
        
        // 更新订单状态
        if (approved) {
            // 退款批准，状态改为6(已退款)
            order.setOrderState(6);
        } else {
            // 退款拒绝，恢复原来的状态
            // 这里简单处理为恢复到之前状态，实际业务可能需要更复杂的逻辑
            order.setOrderState(4); // 已送达
        }
        
        return orderRepository.save(order);
    }
    
    @Override
    public boolean canApplyRefund(Long orderId) {
        Order order = orderRepository.findById(orderId).orElse(null);
        if (order == null) {
            return false;
        }
        
        // 检查是否已有待处理的退款申请
        boolean hasPendingRefund = refundRepository.findByOrderId(orderId).stream()
                .anyMatch(r -> r.getStatus() == 0);
        if (hasPendingRefund) {
            return false;
        }
        
        // 订单状态为2(待接单)、3(制作中)、4(已送达)且没有待处理的退款申请才能申请退款
        return order.getOrderState() >= 2 && order.getOrderState() <= 4;
    }
    
    @Override
    public RefundDto getRefundByOrderId(Long orderId) {
        return refundRepository.findTopByOrderIdOrderByApplyTimeDesc(orderId)
                .map(this::convertToDto)
                .orElse(null);
    }
    
    @Override
    public List<RefundDto> getRefundsByBusinessId(Long businessId) {
        return refundRepository.findByOrder_Business_IdOrderByApplyTimeDesc(businessId).stream()
                .map(this::convertToDto)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<RefundDto> getPendingRefunds() {
        return refundRepository.findByStatusOrderByApplyTimeAsc(0).stream()
                .map(this::convertToDto)
                .collect(Collectors.toList());
    }
    
    @Override
    public RefundDto convertToDto(Refund refund) {
        if (refund == null) {
            return null;
        }
        
        RefundDto dto = new RefundDto();
        dto.setId(refund.getId());
        dto.setOrderId(refund.getOrder().getId());
        dto.setReason(refund.getReason());
        dto.setDetail(refund.getDetail());
        dto.setStatus(refund.getStatus());
        dto.setRejectReason(refund.getRejectReason());
        dto.setApplyTime(refund.getApplyTime());
        dto.setProcessTime(refund.getProcessTime());
        
        // 如果需要，可以设置商家信息
        if (refund.getOrder().getBusiness() != null) {
            BusinessDto businessDto = new BusinessDto();
            // BusinessDto中没有id属性，我们暂时忽略这个设置
            // businessDto.setId(refund.getOrder().getBusiness().getId());
            businessDto.setBusinessName(refund.getOrder().getBusiness().getBusinessName());
            businessDto.setBusinessAddress(refund.getOrder().getBusiness().getBusinessAddress());
            dto.setBusiness(businessDto);
        }
        
        return dto;
    }
} 